<?php

/*
 * CopyRight  : (C)2012-2099 HaoTeam Inc.
 * Document   : User.php
 * Created on : 2023-4-5 16:40:00
 * Author     : Tiger <1192851302@qq.com>
 * Description: This is NOT a freeware, use is subject to license terms.
 *              这即使是一个免费软件,使用时也请遵守许可证条款,得到当时人书面许可.
 *              未经书面许可,不得翻版,翻版必究;版权归属 HaoTeam Inc;
 */

namespace app\api\controller;

use app\Request;
use haoteam\service\UtilService;
use haoteam\service\SessionService;
use think\facade\Cache;
use app\models\User as UserModel;
use app\models\UserBill;
use app\models\UserWithdraw;

/**
 * @title 用户相关
 * Class User
 * Tiger <1192851302@qq.com> 2023-4-5 16:40:00
 */
class User {

    /**
     * @title 用户资料
     * @description 获取和用户资料
     * @author Tiger <1192851302@qq.com>
     * @url /api/user
     * @method POST
     */
    public function material(Request $request) {
        $userInfo = $request->user();
        return app('json')->successful(compact('userInfo'));
    }

    /**
     * @title 更新资料
     * @description 更新用户名和头像等资料
     * @author Tiger <1192851302@qq.com>
     * @url /api/update/material
     * @method POST
     * @param name:nickname type:string require:1 default: other: desc:昵称
     * @param name:avatar type:string require:1 default: other: desc:头像
     */
    public function update_material(Request $request) {
        $data = UtilService::postMore([
                    'nickname',
                    'avatar'
                        ], $request);
        if (empty($data['avatar'])) {
            return app('json')->fail('头像不能为空');
        }
        if (empty($data['nickname'])) {
            return app('json')->fail('昵称不能为空');
        }
        $user_id = $request->uid();
        $userModel = new UserModel();
        $userModel->beginTrans();
        try {
            $userModel->update([
                'nickname' => $data['nickname'],
                'avatar' => $data['avatar']
                    ], ['id' => $user_id]);
            //获取最新的资料
            $user = array_merge($request->user() ?? [], $data);
            //更新缓存
            \haoteam\service\SessionService::instance()->set(compact('user'), $request->token());
            $userModel->commitTrans();
        } catch (\Exception $exc) {
            $userModel->rollbackTrans();
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('资料修改成功');
    }

    /**
     * @title 手机绑定
     * @description 绑定后重新生成Token
     * @author Tiger <1192851302@qq.com>
     * @url /api/phone/bind
     * @method POST
     * @param name:mobile type:string require:1 default:1 other: desc:手机号码
     * @param name:vercode type:string require:1 default:1 other: desc:验证码
     * @return array:数组值#
     */
    public function phone_bind(Request $request) {
        [$mobile, $vercode] = UtilService::postMore([
                    'mobile',
                    'vercode'
                        ], $request, true);
        if (empty($mobile)) {
            return app('json')->fail('手机号不能为空');
        }

        $verifyCode = Cache::get('code_' . $mobile);
        if (empty($verifyCode)) {
            return app('json')->fail('请先获取验证码');
        }
        if (substr($verifyCode, 0, 6) != $vercode) {
            return app('json')->fail('验证码错误');
        }
        if (UserModel::be(['mobile' => $mobile])) {
            return app('json')->fail('验证失败,该号码已存在');
        }
        $userModel = new UserModel();
        $user = $userModel->with(['group', 'verify'])->where('openid', $request->user()['openid'])->withoutField(['password', 'salt'])->find();
        if (empty($user)) {
            return app('json')->fail('账号不存在');
        }

        try {
            //更新资料
            $user->mobile = $mobile;
            $user->save();
            //更新用户资料
            SessionService::instance()->set(compact('user'), $request->token());
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('登陆成功！', ['userInfo' => $user]);
    }

    /**
     * 绑定OPENID
     * @desc 绑定后重新生成Token
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function wechat_bind(Request $request) {
        [$mobile, $vercode, $openid] = UtilService::postMore([
                    'mobile',
                    'vercode',
                    'openid'
                        ], $request, true);
        if (empty($mobile)) {
            return app('json')->fail('手机号不能为空');
        }

        $verifyCode = Cache::get('code_' . $mobile);
        if (empty($verifyCode)) {
            return app('json')->fail('请先获取验证码');
        }
        if (substr($verifyCode, 0, 6) != $vercode) {
            return app('json')->fail('验证码错误');
        }
        if (UserModel::be(['openid' => $openid])) {
            return app('json')->fail('验证失败,该号码已存在');
        }
        $userModel = new UserModel();
        $user = $userModel->with(['group', 'verify'])->where('mobile', $mobile)->withoutField(['password', 'salt'])->find();
        if (empty($user)) {
            return app('json')->fail('账号不存在');
        }

        try {
            //更新资料
            $user->openid = $openid;
            $user->save();
            //更新用户资料
            SessionService::instance()->set(compact('user'), $request->token());
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('登陆成功！', ['userInfo' => $user]);
    }

    /**
     * 更新AppCId
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function update_client(Request $request) {
        [$clientid] = UtilService::postMore([
                    ['clientid', 0]
                        ], $request, true);
        if (empty($clientid)) {
            return app('json')->fail('clientid 为空');
        }
        $user = new UserModel();
        $user->clientid = $clientid;
        $user->save();
        return app('json')->successful();
    }

    /**
     * 用户实名认证
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function prepare_verify(Request $request) {
        $post = UtilService::postMore([
                    'fullname',
                    'identity',
                    'identity_front_image',
                    'identity_back_image'
        ]);
        $post['user_id'] = $request->uid();
        $validate = new \app\api\validates\UserValidate();
        if ($validate->scene('verify')->check($post) == false) {
            return app('json')->fail($validate->getError());
        }
        $post['status'] = 0;
        $userModel = new UserModel();
        $userModel->beginTrans();
        try {
            \app\models\UserVerify::create($post, [], true);
            $userModel->where('id', $post['user_id'])->update(['nickname' => $post['fullname']]);
            $userModel->commitTrans();
        } catch (\Exception $exc) {
            $userModel->rollbackTrans();
            return app('json')->fail($exc->getMessage());
        }

        $orderNo = getRandom();
        try {
            $sdkConfig = \haoteam\service\TencentFaceService::instance()->token()
                    ->ticket($post['user_id'])
                    ->faceid($orderNo, $post['fullname'], $post['identity']);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }

        return app('json')->successful('提交成功', compact('sdkConfig'));
    }

    /**
     * 用户实名认证
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @return type
     */
    public function save_verify(Request $request) {
        $user_id = $request->uid();

        try {
            \app\models\UserVerify::update(['status' => 1], ['user_id' => $user_id]);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        $userModel = new UserModel();
        $user = $userModel->with(['group', 'verify'])->where('id', $user_id)->withoutField(['password', 'salt'])->find();
        //更新用户资料
        SessionService::instance()->set(compact('user'), $request->token());
        return app('json')->successful('认证成功！', ['userInfo' => $user]);
    }

    /**
     * @title 第三方获取手机号
     * @description 获取后自动更新到用户
     * @author Tiger <1192851302@qq.com>
     * @url /api/third/get/phone
     * @method POST
     * @param name:code type:string require:1 default:1 other: desc:code
     * @return array:数组值#
     */
    public function third_get_phone(Request $request) {
        [$code] = UtilService::postMore([
                    ['code', '']
                        ], $request, true);
        if (empty($code)) {
            return app('json')->fail('验证失败,参数有误');
        }
        $user = $request->user();

        try {
            //解密获取用户信息
            $_data = \haoteam\service\EasyWeChatService::miniapp()->getPhoneNumber($code);
            //\think\facade\Log::debug('获取手机号 | ' . json_encode($_data, JSON_UNESCAPED_UNICODE));
        } catch (\Exception $e) {
            return app('json')->fail($e->getMessage());
        }

        $user['mobile'] = $_data['phone_info']['phoneNumber'];

        if (UserModel::be(['mobile' => $user['mobile']])) {
            return app('json')->fail('验证失败,该号码已存在');
        }
        try {
            UserModel::update([
                'mobile' => $user['mobile']
                    ], ['id' => $request->uid()]);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        //更新用户资料
        SessionService::instance()->set(compact('user'), $request->token());

        return app('json')->successful('获取成功', ['userInfo' => $user]);
    }

    /**
     * @title 用户提现
     * @author Tiger <1192851302@qq.com>
     * @url /api/user/withdraw
     * @method POST
     * @param name:money type:string require:1 default: other: desc:提现金额
     * @return array:数组值#
     */
    public function withdraw(Request $request) {
        [$money] = UtilService::postMore([
                    ['money', 0]
                        ], $request, true);
        if ($money <= 0) {
            return app('json')->fail('提现金额不能小于0');
        }
        $UserModel = new UserModel();
        $user = $UserModel->with(['group', 'verify'])->where('id', $request->uid())->withoutField(['password', 'salt'])->find();
        $user->money = bcsub($user->money, $money, 2);
        if ($user->money < 0) {
            return app('json')->fail('账户余额不足');
        }
        $beer_withdraw_min_nomey = \app\models\AdminConfig::getOne('beer_withdraw_min_nomey');
        if ($money < $beer_withdraw_min_nomey) {
            return app('json')->fail('最低提现金额为' . $beer_withdraw_min_nomey);
        }
        $out_batch_no = substr(date("YmdHis") . str_replace('.', '', microtime(true)) . rand(100, 999), 0, 32);
        $out_detail_no = getRandom(20);
        UserModel::beginTrans();
        try {
            $withdraw = UserWithdraw::create([
                        'user_id' => $user->id, 'money' => $money, 'out_batch_no' => $out_batch_no, 'out_detail_no' => $out_detail_no]);
            //保存最新的
            $user->save();
            //写入账单
            UserBill::expend($user->id, $withdraw->id, '转至微信钱包', 'money', 'withdraw', $money, bcsub($user->money_balance, $money, 2));
            //更新用户资料
            SessionService::instance()->set(compact('user'), $request->token());
            UserModel::commitTrans();
        } catch (\Exception $exc) {
            UserModel::rollbackTrans();
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('提现申请，提交成功', ['userInfo' => $user]);
    }

    /**
     * @title 用户账单
     * @description 所有的账单流水
     * @author Tiger <1192851302@qq.com>
     * @url /api/user/bill
     * @method POST
     * @param name:limit type:int require:1 default:10 other: desc:每页数量
     * @param name:page type:int require:1 default:1 other: desc:页码
     * @param name:type type:string require:0 default: other:recharge充值,withdraw提现,withdraw_refuse提现返回,buy_product购买商品,buy_refund退款,invest_income投资收益,agent_income代理收益 desc:账单类型
     * @param name:date type:string require: default:all other:all全部,trid三天,week本周,month本月,last_month上月 desc:日期
     * @return array:数组值#
     */
    public function bill(Request $request) {
        [$category, $type, $date] = UtilService::postMore([
                    ['category', 'money'],
                    ['type', ''],
                    ['date', 'all']
                        ], $request, true);
        $user_id = $request->uid();
        $where = ['user_id' => $user_id, 'category' => $category];
        if (!empty($type)) {
            $where['type'] = explode(',', $type);
        }
        $list = UserBill::getList($where, $date);
        $items = [];
        foreach ($list['items'] as $value) {
            $d = date('Y-m', strtotime($value['time']));
            $items[$d][] = $value;
        }
        return app('json')->successful(['items' => $items, 'code' => 0, 'total' => $list['total']]);
    }

    /**
     * @title 用户充值
     * @description 充值到余额
     * @author Tiger <1192851302@qq.com>
     * @url /api/user/recharge
     * @method POST
     * @param name:id type:int require:1 default: other: desc:套餐ID
     * @return array:数组值#
     */
    public function recharge(Request $request) {
        [$id] = UtilService::postMore(['id'], $request, true);
        $user_id = $request->uid();
        $list = \app\models\Recharge::where('id', $id)->find();
        if (empty($list)) {
            return app('json')->fail('充值方案不存在');
        }
        $out_trade_no = date('YmdHis') . time() . mt_rand(1000, 9999);
        $body = \app\models\AdminConfig::getOne('admin_name') . '用户充值';
        UserModel::beginTrans(); // 启动事务
        try {
            $order = \app\models\UserRecharge::create(['list_id' => $id, 'user_id' => $user_id,
                        'out_trade_no' => $out_trade_no,
                        'buy_nomey' => $list->buy_nomey, 'give_nomey' => $list->give_nomey]);
            $payment = \app\models\Payment::Generate('wecaht', $out_trade_no, $list->buy_nomey, $order->id, $body, '\app\models\UserRecharge');
            UserModel::commitTrans(); // 提交事务
        } catch (\Exception $exc) {
            UserModel::rollbackTrans();  // 回滚事务
            return app('json')->fail($exc->getMessage());
        }
        try {
            $jsConfig = \haoteam\service\EasyWeChatService::bridgeConfig($body, $out_trade_no, $list->buy_nomey);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('订单创建成功', compact('order', 'jsConfig'));
    }
}
